home *** CD-ROM | disk | FTP | other *** search
- /*
- (C) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
- */
-
- /*
- fasl_pass1.c
- DG-SPECIFIC
-
- fasl loader pass1 routines
- */
-
- #include "include.h"
- #include "../h/fasl.h"
- #include "../h/fasl_global.h"
-
- #ifdef AOSVS
- #define ERSNF 077014 /* symbol not found error */
- #endif
- int debug;
-
- init_pass1()
- {
- short i = 0;
-
- fas_buffp = fas_io_buff;
- fas_temp_buff = fas_table_buff;
- fas_routine_addr = 0; /* initialize routine addr */
-
- zero(fas_temp_buff, FAS_BUFF_LEN);
- /* zero((char *)fas_map, FAS_MAP_SIZE * 4); */
- fas_temp_curr = fas_temp_last = 0;
- #ifdef AOSVS
- if (fas_stchan == -1) fasl_openst();
- #endif
- fasl_open_temp();
-
- max_part_no = 0;
- for (i = 1; i <= MAX_SYS_PART; i++)
- fasl_new_table();
-
- fas_relocation_by_table = TRUE;
- vs_base_no = vs_top_no = fas_short_no = -1;
- }
-
- data_pass1()
- {
- FAS_HDR_P hdr_p;
- FAS_DATA_P data_p;
- short base, reloc, reloc_ex;
- short *base_p, *dword_p;
- int obnum, repeat_count, displacement;
- int words, total_len, over_write;
-
- /* set up pointers */
- hdr_p = (FAS_HDR_P)fas_buffp;
- data_p = (FAS_DATA_P)(fas_buffp + FAS_HEADER_BLEN);
-
- obnum = hdr_p->hdr_num; /* block number */
- base = data_p->data_base;
- if (datab_rev < 2)
- repeat_count = 1;
- else
- repeat_count = data_p->data_repeat;
- words = (int)(data_p->data_words) * repeat_count;
-
- if (base > max_part_no) fasl_invalid();
-
- /* relocation */
- base_p = &base;
- dword_p = &(data_p->data_disp);
- reloc = (data_p->data_reloc) & RELOC_OP;
- reloc_ex = ((data_p->data_reloc) & RELOC_OP_EX) >> RELOC_OP_S;
- if (reloc != EX_RELOC) unexpect_reloc(reloc);
-
- relocation(reloc_ex, base_p, dword_p);
-
- displacement = data_p->data_disp;
- part_table_p = fasl_get_table(base);
- total_len = part_table_p->part_len;
- if ((displacement + words) > total_len)
- total_len = displacement + words;
- part_table_p->part_len = total_len;
- }
-
- titl_pass1()
- {
- FAS_HDR_P hdr_p;
- FAS_TITL_P titl_p;
-
- short bnum;
- char title_buff[MAX_TITLE+1];
- char *work_ptr, *work_ptr1;
- short title_len;
-
- bnum = ((FAS_HDR_P)fas_buffp)->hdr_num;
- if (bnum != 1) fasl_invalid();
-
- /*
- titl_p = (FAS_HDR_P)(fas_buffp + FAS_HEADER_BLEN);
-
- title_len = titl_p->titl_len;
- work_ptr = fas_buffp + (titl_p->titl_ptr);
- work_ptr1 = title_buff;
-
- while ( title_len-- > 0)
- *(work_ptr1++) = *(work_ptr++);
- *work_ptr1 = '\0';
-
- if (debug) printf("; Loading %s\n",title_buff);
- */
- }
-
- ext_pass1()
- {
- FAS_HDR_P hdr_p;
- FAS_ENT_P ent_p;
- FAS_NAME_P name_p;
-
- short base, sym_count, symbol_len;
- char *work_ptr, *work_ptr1;
- int symval;
- int ier;
-
- /* set up pointers */
- hdr_p = (FAS_HDR_P)fas_buffp;
- ent_p = (FAS_ENT_P)(fas_buffp + FAS_HEADER_BLEN);
- name_p = (FAS_NAME_P)(ent_p + 1);
-
- sym_count = ent_p->ent_count;
-
- while (sym_count-- > 0) {
- part_table_p = fasl_new_table();
- part_table_p->part_symbol = TRUE;
- /* set symbol flag */
- symbol_len = (name_p->name_len) & L_MASK;
-
- work_ptr = fas_buffp + (name_p->name_ptr);
- work_ptr1 = part_table_p->part_name;
- while(symbol_len-- > 0) /* copy symbol */
- *work_ptr1++ = *work_ptr++;
- ier = fasl_st(part_table_p->part_name, &symval);
- #ifdef AOSVS
- if (ier != 0)
- if (ier == ERSNF)
- /* ignore .REQUIRE_LANG_RT_REV_??.?? */
- if ((name_p->name_len) & L_MASK < 16 ||
- strncmp(part_table_p->part_name,
- ".REQUIRE_LANG_RT", 16) != 0) {
- fasl_undefined(part_table_p->part_name);
- } else {
- part_table_p->part_addr = -1;
- }
- else
- sys_emes(ier);
- else
- part_table_p->part_addr = symval;
- #endif
- #ifdef DGUX
- if (ier != 0)
- /* ignore .REQUIRE_LANG_RT_REV_??.?? */
- if ((name_p->name_len) & L_MASK < 16 ||
- strncmp(part_table_p->part_name,
- ".REQUIRE_LANG_RT", 16) != 0) {
- fasl_undefined(part_table_p->part_name);
- } else
- part_table_p->part_addr = -1;
- else
- part_table_p->part_addr = symval;
- #endif
-
- name_p += 1; /* advance for next symbol */
- }
- }
-
- pat_pass1()
- {
- FAS_HDR_P hdr_p;
- FAS_PAT_P pat_p;
- FAS_PATD_P patd_p;
-
- short base, pat_count, flags;
- long p_len; /* partition length */
- short p_name_len; /* partion name length */
- char *work_ptr, *work_ptr1;
- int symval;
- int ier;
-
- /* set up pointers */
- hdr_p = (FAS_HDR_P)fas_buffp;
- pat_p = (FAS_PAT_P)(fas_buffp + FAS_HEADER_BLEN);
- patd_p = (FAS_PATD_P)(pat_p + 1);
-
- pat_count = pat_p->pat_count;
-
- while (pat_count-- > 0) { /* for each descripter */
- part_table_p = fasl_new_table();
-
- flags = patd_p->patd_flag; /* various flags */
- part_table_p->part_align = (flags & PAT_ALN) >> PAT_ALN_S;
- if (part_table_p->part_align > 1) fasl_align_error();
-
- part_table_p->part_global = (flags & PAT_BASE) >> PAT_BASE_S;
- part_table_p->part_len = patd_p->patd_len;
- p_name_len = (patd_p->patd_nlen) & L_MASK;
-
- /* check short NREL */
- if (((flags & PAT_NREL) != 0) &&
- (part_table_p->part_global == FALSE)) {
- /* part_table_p->part_addr = fas_short_nrel; */
- fas_short_no = part_table_p->part_no;
- goto NEXT;
- }
- work_ptr = fas_buffp + (patd_p->patd_nptr);
- work_ptr1 = part_table_p->part_name;
- while (p_name_len-- > 0) /* copy name */
- *work_ptr1++ = *work_ptr++;
-
- if (vs_base_no < 0 &&
- strcmp(part_table_p->part_name, "vs_base") == 0)
- vs_base_no = part_table_p->part_no;
- else if (vs_top_no < 0 &&
- strcmp(part_table_p->part_name, "vs_top") == 0)
- vs_top_no = part_table_p->part_no;
-
- if (part_table_p->part_global == FALSE) goto NEXT;
- ier = fasl_st(part_table_p->part_name, &symval);
- #ifdef AOSVS
- if (ier == ERSNF) {
- FEerror("Internal entry ~S not found.", 1,
- make_simple_string(part_table_p->part_name));
- } else
- if (ier != 0)
- sys_emes(ier);
- else
- part_table_p->part_addr = symval;
- #endif
- #ifdef DGUX
- if (ier != 0) {
- FEerror("Internal entry ~S not found.", 1,
- make_simple_string(part_table_p->part_name));
- } else
- part_table_p->part_addr = symval;
-
- #endif
- NEXT:
- patd_p += 1; /* advance for next */
- }
- }
-
- rev_pass1()
- {
- FAS_HDR_P hdr_p;
- FAS_REV_P rev_p;
- FAS_REVD_P revd_p;
-
- short bnum, rev_count, block_type;
-
- bnum = ((FAS_HDR_P)fas_buffp)->hdr_num;
- if (bnum != 2) fasl_invalid();
-
- rev_p = (FAS_REV_P)(fas_buffp + FAS_HEADER_BLEN);
- revd_p = (FAS_REVD_P)(rev_p + 1);
-
- rev_count = rev_p->rev_count;
-
- while ( rev_count-- > 0) {
- block_type = (revd_p->revd_btyp) & BLOCK_TYPE;
- if (block_type != DATA_BLOCK) continue;
- datab_rev = (revd_p->revd_brev); /* data block rev */
-
- if (datab_rev > 2) fasl_rev_error();
-
- revd_p += 1; /* advance for next */
- }
- }
-
- aln_pass1()
- {
- FAS_HDR_P hdr_p;
- FAS_ALN_P aln_p;
-
- short base, power;
-
- aln_p = (FAS_ALN_P)(fas_buffp + FAS_HEADER_BLEN);
-
- base = aln_p->aln_base;
- part_table_p = fasl_get_table(base);
- part_table_p->part_align = aln_p->aln_power;
- }
-
- unexpected()
- {
-
- short block_type, block_num;
-
- block_type = (((FAS_HDR_P)fas_buffp)->hdr_typ) & BLOCK_TYPE;
- block_num = ((FAS_HDR_P)fas_buffp)->hdr_num;
-
- if (debug) {
- printf("unexpected FASL block\n");
- printf(" block type : %d\n", block_type);
- printf(" block number : %d\n", block_num);
- }
- fasl_invalid();
- }
-
- /* set symbol value in partition table */
- /*
- fasl_ssym()
- {
- int symval, i, ier;
- char *symp;
-
- for (i = MAX_SYS_PART + 1; i <= max_part_no; i++) {
- part_table_p = fasl_get_table(i);
- if ((part_table_p->part_symbol == FALSE) &&
- (part_table_p->part_global == FALSE)) continue;
- symp = part_table_p->part_name;
- ier = fasl_st(symp, &symval);
- #ifdef AOSVS
- if (ier == ERSNF)
- if (part_table_p->part_symbol == TRUE)
- fasl_undefined(symp);
- else
- continue;
- else
- if (ier != 0) sys_emes(ier);
- #endif
- #ifdef DGUX
- if (ier != 0)
- if (part_table_p->part_symbol == TRUE) fasl_undefined(symp);
- #endif
- part_table_p->part_addr = symval;
- }
- }
- */
-
- fasl_len()
- {
-
- int caddr, p_len;
- short p_align, i;
-
- caddr = 0;
- for (i = 0; i < max_part_no; i++) {
- if (i == fas_short_no) continue;
- part_table_p = fasl_get_table(i);
- if ((part_table_p->part_global == TRUE) &&
- (part_table_p->part_addr != 0)) continue;
- p_len = part_table_p->part_len;
- p_align = part_table_p->part_align;
- caddr = fasl_align(caddr, p_align) + p_len;
- }
- caddr += 2;
- /* 1 word for actual length
- 1 word for alignment gap */
- /* warning : for above alignment gap to be proper
- all alignment power must be less or equal to 1 */
-
- return(caddr);
- }
-
- fasl_align(caddr, power)
- int caddr;
- short power;
- {
- int mask;
-
- mask = (1 << power) - 1;
- if ((caddr & mask) == 0) return(caddr);
- return((caddr | mask) + 1);
- }
-
- fasl_saddr()
- {
- short *caddr;
- int i, part_len;
- int recno, ind;
- short part_align;
-
- caddr = fas_rstart; /* set current to starting addr */
- fas_addr_rec_first = fas_temp_last + 1;
- fas_addr_rec_curr = 0;
-
- zero(fas_addr_buff, FAS_BUFF_LEN);
-
- for (i = 0; i <= max_part_no; i++) {
- part_table_p = fasl_get_table(i);
- if ((part_len = part_table_p->part_len) == 0 ||
- part_table_p->part_addr != 0) {
- recno = i / FAS_ADDRS_IN_REC;
- ind = i % FAS_ADDRS_IN_REC;
- if (recno > fas_addr_rec_curr) {
- fasl_write_addr_rec(fas_addr_rec_curr);
- fas_addr_rec_curr++;
- zero(fas_addr_buff, FAS_BUFF_LEN);
- }
- ((int *)fas_addr_buff)[ind] = part_table_p->part_addr;
- continue;
- }
- part_align = part_table_p->part_align;
- caddr = fasl_align((int)caddr, part_align);
- part_table_p->part_addr = caddr;
- recno = i / FAS_ADDRS_IN_REC;
- ind = i % FAS_ADDRS_IN_REC;
- if (recno > fas_addr_rec_curr) {
- fasl_write_addr_rec(fas_addr_rec_curr);
- fas_addr_rec_curr++;
- zero(fas_addr_buff, FAS_BUFF_LEN);
- }
- ((int *)fas_addr_buff)[ind] = caddr;
- caddr = caddr + part_len;
- }
- fasl_write_addr_rec(fas_addr_rec_curr);
- }
-
- check_short_area()
- {
- if (fas_short_no < 0) return;
- part_table_p = fasl_get_table(fas_short_no);
- if (part_table_p->part_len == 0) return;
- if (fas_short_nrel + part_table_p->part_len > fas_short_end)
- FEerror("Not enough FASL short nrel area.", 0);
-
- part_table_p->part_addr = fas_short_nrel;
-
- /* for next */
- fas_short_nrel += part_table_p->part_len;
- }
-